package view.transitions;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

public class Dissolve extends Animator {
	public static final int	MIN_MOSAIC_SIZE	= 15;
	private int				mosaic_size;
	private float[][]		mosaics;
	private BufferedImage	buffer;

	public Dissolve(BufferedImage from, BufferedImage to) {
		super(from, new BufferedImage(to.getWidth(), to.getHeight(), BufferedImage.TYPE_INT_ARGB));
		this.buffer = to;
		this.mosaic_size = Math.min(this.overlay.getWidth(), this.overlay.getHeight()) / 15;
		if (MIN_MOSAIC_SIZE > this.mosaic_size) {
			this.mosaic_size = MIN_MOSAIC_SIZE;
		}
		int numMosaicsVertical = this.overlay.getHeight() / this.mosaic_size
				+ ((this.overlay.getHeight() % this.mosaic_size == 0) ? 0 : 1);
		int numMosaicsHorizontal = this.overlay.getWidth() / this.mosaic_size
				+ ((this.overlay.getWidth() % this.mosaic_size == 0) ? 0 : 1);
		this.mosaics = new float[numMosaicsHorizontal][numMosaicsVertical];
	}

	@Override
	public void animate() {
		this.currentFrame++;
		// this.overlay = new BufferedImage(buffer.getWidth(),
		// buffer.getHeight(),
		// BufferedImage.TYPE_INT_ARGB);

		Graphics2D g2d = (Graphics2D) this.overlay.getGraphics();
		AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0);
		for (int i = 0; i < this.mosaics.length; i++) {
			for (int j = 0; j < this.mosaics[i].length; j++) {

				if (Math.random() < (float) this.currentFrame / MAX_FRAMES) {
					this.mosaics[i][j] += (float) Math.random() / MAX_FRAMES;
					if (this.mosaics[i][j] >= 1) {
						this.mosaics[i][j] = 1;
					}

					g2d.setComposite(alpha.derive(this.mosaics[i][j]));
					g2d.setClip(null);
					g2d.clipRect(i * this.mosaic_size, j * this.mosaic_size, this.mosaic_size, this.mosaic_size);
					// g2d.drawImage(buffer, 0, 0, null);
					g2d.drawImage(this.buffer, i * this.mosaic_size, j * this.mosaic_size, i * this.mosaic_size
							+ this.mosaic_size, j * this.mosaic_size + this.mosaic_size, i * this.mosaic_size, j
							* this.mosaic_size, i * this.mosaic_size + this.mosaic_size, j * this.mosaic_size
							+ this.mosaic_size, null);
				}
			}
		}
	}
}
